#include "common.h"
S4B Receive(PMESSAGE pmessage,U4B type)
{
   PPROCESS ppro=WhoRunning;
   Assert((ppro->p_messageplace!=ppro->p_messageget));
   if(ppro->p_messageplace==ppro->p_messageget || ppro->p_pmessage==PTR_INVALID)
     return ARTIST_ERROR_MESSAGEMECHANISMERROR;
   if(type==RECEIVE_SEQUENTIAL)
  {   

       if(ppro->p_messageheader==PTR_INVALID)
       { 
          if(((ppro->p_messageget+1)%ppro->p_messagelimit)==ppro->p_messageplace)
            return ARTIST_ERROR_MESSAGEBUFFEREMPTY;
          ppro->p_messageget=((ppro->p_messageget+1)%ppro->p_messagelimit);
          *pmessage=ppro->p_pmessage[ppro->p_messageget];
   //  Print("receive %s,message %X",WhoRunning->p_name,(*pmessage).type);
          return ARTIST_ERROR_OK;
       }
       if(((ppro->p_messageget+1)%ppro->p_messagelimit)==ppro->p_messageplace) /*The message buffer is empty,but wait queue not.*/
       {
          PPROCESS hook;
          MESSAGE  shack;
          MemorySet(&shack,sizeof(MESSAGE),0);
          shack.type=TYPE_INVALID;/*INVALID*/
          *pmessage=ppro->p_messageheader->p_messageshack;
          hook=ppro->p_messageheader;
          ppro->p_messageheader=ppro->p_messageheader->p_messagequeue;
          hook->p_messagequeue=(PPROCESS)PTR_INVALID;
          hook->p_messageshack=shack;
          hook->p_state=STATE_READY;
          return ARTIST_ERROR_OK;
       }
       if(((ppro->p_pmessage[((ppro->p_messageget+1)%ppro->p_messagelimit)]).destination>=((ppro->p_messageheader->p_messageshack).destination)))
       {
          PPROCESS hook;
          MESSAGE  shack;
          MemorySet(&shack,sizeof(MESSAGE),0);
          shack.type=TYPE_INVALID;/*INVALID*/
          *pmessage=ppro->p_messageheader->p_messageshack;
          hook=ppro->p_messageheader;
          ppro->p_messageheader=ppro->p_messageheader->p_messagequeue;
          hook->p_messagequeue=(PPROCESS)PTR_INVALID;
          hook->p_messageshack=shack;
          hook->p_state=STATE_READY;
          return ARTIST_ERROR_OK;
       }
       else
       {
          ppro->p_messageget=((ppro->p_messageget+1)%ppro->p_messagelimit);
          *pmessage=ppro->p_pmessage[ppro->p_messageget];
          return ARTIST_ERROR_OK;
       }
  }
   return ARTIST_ERROR_UNKNOWN;
//   MESSAGE message=*pmessage;
//Print("message:%X,%X,%X,%X",message.source,message.destination,message.type,message.pvalue);
//   return 0;
}
S4B ReceiveMessage(PMESSAGE pmessage)
{
    S4B value;//Assert(0);
    SystemCallInterrupt((U4B)SYSCALL_RECEIVEMESSAGE,(U4B)pmessage,RECEIVE_SEQUENTIAL,(U4B)&value);
    return value;
}

